<template>
    <ul class="flex flex-row items-center gap-[6px] flex-wrap" @click.stop>
        <li class="tag group" v-for="tag of limitedTags" :key="tag.value">
            {{ tag.label }}
            <GpFontIcon name="icon-guanbi" class="!text-xl hover:text-theme hidden group-hover:block cursor-pointer" @click="handleDel(tag)" v-if="!disInteract" />
        </li>
        <li class="tag tag-empty" v-if="tags?.length === 0">
            暂无标签
        </li>
        <a-popover trigger="click" :title="null" placement="bottomLeft" :arrow="false" :open="clickOpen" @open-change="handleClickOpenChange"
            :overlay-style="{ width: '240px', borderRadius: '4px' }" :overlay-inner-style="{ padding: 0 }" v-if="showPlusTag">
            <li class="tag tag-plus">
                <a-popover trigger="hover" :title="null" placement="bottom" :arrow="false" :open="hoverOpen" @open-change="handleHoverOpenChange"
                    :overlay-style="{ width: '240px', borderRadius: '4px' }" :overlay-inner-style="{ padding: '12px' }">
                    <span class="!text-[13px] !leading-3 cursor-pointer">+{{ limitTag && tags!.length > maxTagCount ? tags?.length : '' }}</span>
                    <template #content>
                        <ul class="flex flex-row flex-wrap gap-[6px] max-h-[360px] overflow-auto">
                            <li class="tag" v-for="tag of tags" :key="tag.value">{{ tag.label }}</li>
                        </ul>
                    </template>
                </a-popover>
            </li>
            <template #content>
                <div class="box-border">
                    <form autocomplete="off" class="border-b border-solid border-b-[#EEEEEE] focus-within:border-b-theme mx-3" @submit.prevent>
                        <a-input v-model:value="createText" @input="handleSearchTags()" name="name" :maxlength="10" placeholder="查找或创建标签" size="large" :bordered="false" allow-clear style="font-size: 14px; padding-block: 12px;" />
                    </form>
                    <a-spin spinning tip="搜索中..." v-if="loading">
                        <div class="w-full h-25"></div>
                    </a-spin>
                    <ul class="flex flex-col gap-1 pt-4 pb-5 max-h-[360px] overflow-auto" v-else-if="searchedList && searchedList.length > 0">
                        <li v-for="searched of searchedList" :key="searched.value" class="px-3 hover:bg-[#F8F9FF] py-1 cursor-pointer flex flex-row items-center justify-between gap-1 group" data-searched>
                            <div v-if="editMode.enabled && editMode.key === searched.value" class="border border-solid border-theme bg-white rounded-sm text-primary text-[13px]">
                                <a-input autocomplete="off" v-model:value="searched.changedLabel" style="height: 20px;" :bordered="false" placeholder="请输入标签名称" @blur="handleCancelRenameTag(searched)" @press-enter="handleAddUpdatedTag(searched)" />
                            </div>
                            <template v-else>
                                <div class="tag" @click="handleDirectAddTag(searched)">{{ searched.label!.length > 8 ? `${searched.label?.slice(0, 8)}...` : searched.label }}</div>
                                <a-space :size="10" style="flex: none;" class="!hidden group-hover:!inline-flex">
                                    <GpFontIcon name="icon-bianji" class="!text-sm hover:text-theme" @click="handleTriggerEdit(searched, $event)"/>
                                    <GpFontIcon name="icon-shanchu3" class="!text-sm hover:text-theme" @click="handleTriggerRemove(searched)"/>
                                </a-space>
                            </template>
                        </li>
                    </ul>
                    <div class="py-3" v-else>
                        <div class="bg-[#F8F9FF] h-[28px] flex flex-row items-center gap-1 text-[13px] px-3">
                            <span class="text-[#496EA9] flex-none">创建标签</span>
                            <span class="text-primary truncate flex-1 w-0">{{ createText }}</span>
                        </div>
                        <div class="flex flex-row justify-end mt-5 box-border px-3">
                            <a-button type="primary" style="height: 28px; font-size: 12px;" :disabled="!createText || createText.trim().length <= 0" @click="handleAddCreatedTag()">确认</a-button>
                        </div>
                    </div>
                </div>
            </template>
        </a-popover>
    </ul>
</template>
<script lang="ts" setup>
import type { Int64SelectCheckableTag, Int64SelectOption } from '@/api/siderBar/model';
import { useAppStore } from '@/stores';
import { message } from 'ant-design-vue';

/** @mock */
function postResumeQuicktags(args: any) {
    return Promise.resolve(args)
}
/** @mock */
function deleteResumeDeleteresumetagId(args: any) {
    return Promise.resolve(args)
}
/** @mock */
function postResumeAddresumetag(args: any) {
    return Promise.resolve(args)
}
type Searched = Int64SelectOption & {
    changedLabel?: string
}
defineOptions({
    name: 'GpResumeTag',
    inheritAttrs: true
});
const { resumeId, maxTagCount = 2, limitTag = true, disInteract = false } = defineProps<{
    resumeId: number
    /** @default 2 */
    maxTagCount?: number
    /** @default true */
    limitTag?: boolean
    /** @default false */
    disInteract?: boolean
}>()
const emit = defineEmits<{
    success: []
}>()
const appStore = useAppStore()
const tags = defineModel<Int64SelectCheckableTag[]>("tags")
const limitedTags = computed(() => {
    if (limitTag) {
        return tags.value?.slice(0, maxTagCount)
    }
    return tags.value
})
const createText = ref<string>()
const hoverOpen = ref(false)
const clickOpen = ref(false)
const editMode = ref({
    key: -1,
    enabled: false
})
const { data: searchedList, mutate, runAsync, loading } = useRequest((keywords?: string) => postResumeQuicktags({
    keywords,
    top: 20,
    notValues: tags.value?.map(l => l.value)
}).then(res => {
    const changedRes: Searched[] = res.map(l => ({ ...l, changedLabel: l.label }))
    return changedRes
}), {
    manual: true,
    initialData: [],
    debounceInterval: 300,
    debounceOptions: {
        trailing: true,
    }
})
const showPlusTag = computed(() => {
    if (disInteract) {
        if (tags.value && tags.value.length > 0 && limitTag && tags!.length > maxTagCount) {
            return true
        }
        return false
    }
    return true
})
function handleHoverOpenChange(visible: boolean) {
    if (clickOpen.value || tags.value?.length === 0) return
    hoverOpen.value = visible
}
function handleClickOpenChange(visible: boolean) {
    if (disInteract) return
    if (visible) {
        hoverOpen.value = false
    }
    clickOpen.value = visible
}
function handleSearchTags(){
    runAsync(createText.value)
}
function handleTriggerEdit(item: Searched, e: MouseEvent) {
    editMode.value.enabled = true
    editMode.value.key = item.value
    if (e) {
        const searchedEl = (<HTMLElement>e.target).closest("[data-searched]")
        nextTick(() => {
            searchedEl?.querySelector('input')?.focus()
        })
    }
}
function handleResetEdit() {
    editMode.value.enabled = false
    editMode.value.key = -1
}
function handleTriggerRemove(item: Searched) {
    mutate(list => list.filter(l => l.value !== item.value))
}
function handleCancelRenameTag(item: Searched) {
    item.changedLabel = item.label
    handleResetEdit()
}
async function handleDirectAddTag(item: Searched) {
    try {
        appStore.toggleLoading(true)
        await postResumeAddresumetag({
            name: item.label!,
            tagId: item.value,
            resumeId,
        })
        appStore.toggleLoading(false)
        message.success('添加成功')
        emit('success')
    } catch (error) {
        appStore.toggleLoading(false)
    }
}
async function handleAddUpdatedTag(item: Searched) {
    try {
        const tirmedLabel = item.changedLabel!.trim()
        if (tirmedLabel.length <= 0) {
            handleCancelRenameTag(item)
            return
        }
        appStore.toggleLoading(true)
        await postResumeAddresumetag({
            name: tirmedLabel,
            tagId: item.value,
            resumeId,
        })
        appStore.toggleLoading(false)
        message.success('添加成功')
        handleCancelRenameTag(item)
        emit('success')
    } catch (error) {
        handleCancelRenameTag(item)
        appStore.toggleLoading(false)
    }
}
async function handleAddCreatedTag() {
    try {
        appStore.toggleLoading(true)
        const name = createText.value!.trim()
        await postResumeAddresumetag({
            name,
            resumeId,
        })
        appStore.toggleLoading(false)
        message.success('添加成功')
        emit('success')
    } catch (error) {
        appStore.toggleLoading(false)
    }
}
async function handleDel(tag: Int64SelectCheckableTag) {
    try {
        appStore.toggleLoading(true)
        await deleteResumeDeleteresumetagId(tag.value)
        appStore.toggleLoading(false)
        message.success('删除成功')
        emit('success')
    } catch (error) {
        appStore.toggleLoading(false)
    }
}
</script>
<style lang="less" scoped>
@reference "../../assets/styles/tailwind.css";

.tag {
    font-size: 13px;
    @apply box-border px-2 h-5 flex flex-row items-center gap-1 rounded-sm border border-solid border-[#496EA9]/40 text-[#324366] flex-none;
}

.tag-empty {
    @apply text-[#324366]/60;
}

.tag-plus {
    @apply hover:text-theme gap-0;
}
</style>